# coding:utf-8
# 测试案例的管理
from __future__ import division
import json, datetime, difflib
from MCaseManage import BaseCase, HisModify, db, CaseSubPlan, CasePlan, CaseResult
from httpApi.MHttpApi import Project
from sqlalchemy import not_, and_, or_
import UserManage.userBussiness


def baseCase_isCasePlan_exist(project_id, case_plan):
    query = db.session().query(BaseCase)
    query = query.filter(and_(BaseCase.project_id == project_id, BaseCase.case_plan == case_plan))
    query = query.filter(BaseCase.is_show == 0)
    query = query.first()
    if query:
        return True
    return False


def baseCase_allModel(project_id, case_plan):
    """查询出项目中现存的测试用例中的所有的模块"""
    query = db.session().query(BaseCase)

    if project_id != "" and case_plan != "":
        query = query.filter(and_(BaseCase.project_id == project_id, BaseCase.case_plan == case_plan))
    query = query.filter(BaseCase.is_show == 0)
    #   去掉重复的模块
    query = query.group_by(BaseCase.case_main_mod)
    query = query.order_by(BaseCase.id.desc())
    list = []
    for d in query.all():
        c = d.__dict__
        del (c['_sa_instance_state'])
        list.append(c)
    return list


def baseCase_allPlan(project_id):
    query = db.session().query(BaseCase)
    if project_id != "":
        query = query.filter(and_(BaseCase.project_id == project_id))
    query = query.filter(BaseCase.is_show == 0)
    query = query.group_by(BaseCase.case_plan)
    query = query.order_by(BaseCase.id.desc())
    list = []
    for d in query.all():
        c = d.__dict__
        del (c['_sa_instance_state'])
        list.append(c)
    return list


def baseCase_del(id):
    query = BaseCase.query.filter(BaseCase.id == id).first()
    if query:
        query.is_show = 1
        db.session.commit()
        HisModify(query.id, 0, '', 3, '').add()
        return query.id
    return False


def different_toHtml(text1, text2):
    text1_lines = text1.splitlines()
    text2_lines = text2.splitlines()
    # d = difflib.HtmlDiff()
    # diff = d.make_file(text1_lines, text2_lines)
    d = difflib.Differ()
    diff = d.compare(text1_lines, text2_lines)
    return '\n'.join(diff)


def baseCase_manage(content):
    """保存或者更新用例"""
    if content['case_pri'] == "":
        content['case_pri'] = "中"
    if content.has_key("id"):
        if content['id'] != "":
            query = BaseCase.query.filter(BaseCase.id == content['id']).first()

            if query:
                #   如果查询出来的内容跟提交上来的内容一样，则什么也不做
                c = query.__dict__
                if content.has_key("_sa_instance_state"):
                    del (c['_sa_instance_state'])
                if c == content:
                    return query.id
                oldText = "case_title:%s\r\ncase_step:%s\r\ncase_expect:%s" % (
                    query.case_title, query.case_step, query.case_expect)
                newText = "case_title:%s\r\ncase_step:%s\r\ncase_expect:%s" % (
                    content.get('case_title'), content.get('case_step'), content.get('case_expect'))
                query.project_id = content['project_id']
                query.case_pre = content['case_pre']
                query.case_title = content['case_title']
                query.case_require_no = content['case_require_no']
                query.case_main_mod = content['case_main_mod']
                query.case_pri = content['case_pri']
                query.case_step = content['case_step']
                query.case_second_mod = content['case_second_mod']
                query.case_expect = content['case_expect']
                query.case_note = content['case_note']
                query.in_person = content['in_person']
                query.up_person = content['up_person']
                query.imag_desc = content['imag_desc']
                query.autofun = content['autofun']
                query.case_fun = content['case_fun']
                query.update_time = str(datetime.datetime.now())
                db.session.commit()
                if oldText != newText:
                    modify_ctn = different_toHtml(oldText, newText)
                    caseId = query.id
                    HisModify(caseId, 0, modify_ctn, 1, content['up_person']).add()
                return query.id
    id = BaseCase(project_id=content['project_id'],
                  case_type=0,
                  case_plan=content['case_plan'],
                  case_pre=content['case_pre'],
                  case_title=content['case_title'],
                  case_require_no=content['case_require_no'],
                  case_main_mod=content['case_main_mod'],
                  case_pri=content['case_pri'],
                  case_step=content['case_step'],
                  case_second_mod=content['case_second_mod'],
                  case_expect=content['case_expect'],
                  case_note=content['case_note'],
                  in_person=content['in_person'],
                  up_person=content['up_person'],
                  imag_desc=content['imag_desc'],
                  autofun=content['autofun'],
                  case_fun=content['case_fun']).add()
    HisModify(id, 0, '', 0, content['up_person']).add()
    return id


def baseCase_srh(project_id, case_plan, case_pri, case_main_mod, key_words, page, limit):
    """
    根据关键字查询用例。相同的case_plan一定拥有相同的case_type。所以在添加时要判断case_plan一定不能重复
    """
    query = db.session().query(BaseCase)
    list = []
    if project_id != "" and case_plan != "":
        query = query.filter(and_(BaseCase.project_id == project_id, BaseCase.case_plan == case_plan))
        if case_pri != "":
            query = query.filter(BaseCase.case_pri == case_pri)
        if case_main_mod != "":
            query = query.filter(BaseCase.case_main_mod == case_main_mod)
        if key_words != "":
            key_words = "%%%s%%" % key_words
            query = query.filter(or_(BaseCase.case_require_no.like(key_words),
                                     BaseCase.case_no.like(key_words),
                                     BaseCase.case_main_mod.like(key_words),
                                     BaseCase.case_second_mod.like(key_words),
                                     BaseCase.case_pri.like(key_words),
                                     BaseCase.case_pre.like(key_words),
                                     BaseCase.case_title.like(key_words),
                                     BaseCase.case_step.like(key_words),
                                     BaseCase.case_expect.like(key_words),
                                     BaseCase.case_note.like(key_words)))
        query = query.filter(BaseCase.is_show == 0)
        count = query.count()
        data = query.paginate(int(page), int(limit), False)

        for d in data.items:
            c = d.__dict__
            up_person = c['up_person']
            up_person = UserManage.userBussiness.getNameById(up_person)
            c['up_person_name'] = up_person
            del (c['_sa_instance_state'])
            list.append(c)
        return list, count


def baseCase_gotMyDo(userId, project_version=None):
    """获取我的测试执行任务"""
    query = db.session().query(CasePlan, CaseSubPlan, Project)
    query = query.join(CasePlan, CaseSubPlan.case_plan_id == CasePlan.id)

    query = query.filter(
        and_(CasePlan.work_state == 0, CaseSubPlan.work_type == 1, CaseSubPlan.person == userId,
             Project.id == CasePlan.project_id))
    if project_version:
        query = query.filter(CasePlan.project_version == project_version)
    query = query.group_by(CasePlan.project_version)
    query = query.all()
    list = []
    for d in query:
        list.append({"project_id": d.CasePlan.project_id, 'project_version': d.CasePlan.project_version,
                     'work_content': d.CaseSubPlan.work_content, 'project_name': d.Project.project_name})
    return list


def baseCase_getTask_doCase(project_id, project_version, case_priList, resultList, case_main_mod_list, case_plan,
                            key_words,
                            page, limit):
    """获取测试用例来扫行测试"""
    caseQuery = db.session().query(BaseCase)
    # resultQuery = db.session().query(CaseResult)
    case_plan = case_plan.split(',')
    caseQuery = caseQuery.filter(and_(BaseCase.project_id == project_id, BaseCase.case_plan.in_(case_plan)))
    if case_priList != "":
        case_priList = case_priList.split(',')
        caseQuery = caseQuery.filter(BaseCase.case_pri.in_(case_priList))
    if case_main_mod_list != "":
        case_main_mod_list = case_main_mod_list.split(',')
        caseQuery = caseQuery.filter(BaseCase.case_main_mod.in_(case_main_mod_list))
    if key_words != "":
        key_words = "%%%s%%" % key_words
        caseQuery = caseQuery.filter(or_(BaseCase.case_require_no.like(key_words),
                                         BaseCase.case_no.like(key_words),
                                         BaseCase.case_main_mod.like(key_words),
                                         BaseCase.case_second_mod.like(key_words),
                                         BaseCase.case_pri.like(key_words),
                                         BaseCase.case_pre.like(key_words),
                                         BaseCase.case_title.like(key_words),
                                         BaseCase.case_step.like(key_words),
                                         BaseCase.case_expect.like(key_words),
                                         BaseCase.case_note.like(key_words)))
    caseQuery = caseQuery.filter(BaseCase.is_show == 0)
    count = caseQuery.count()
    data = caseQuery.paginate(int(page), int(limit), False)
    list = []
    for d in data.items:
        c = d.__dict__
        up_person = c['up_person']
        up_person = UserManage.userBussiness.getNameById(up_person)
        c['up_person_name'] = up_person
        #   根据id和project_version去结果库进行查询
        del (c['_sa_instance_state'])
        result = case_result(c['id'], project_version)
        if resultList != "":
            if result.get('result') not in resultList.split(','):
                continue

        list.append(dict(c, **result))
    return list, count


def case_result(caseId, project_version):
    query = CaseResult.query.filter(
        and_(CaseResult.case_id == caseId, CaseResult.project_version == project_version)).first()
    if query:
        c = query.__dict__
        del (c['_sa_instance_state'])
        c['result_id'] = c['id']
        del (c['id'])
        return c
    else:
        return {'result_id': '', 'case_id': '', 'project_version': '', 'result': '', 'bug_url': '', 'bug_des': '',
                'person': ''}


def case_result_manage(content):
    """提交测试结果"""
    if content.has_key("result_id"):
        if content['result_id'] != "":
            query = CaseResult.query.filter(CaseResult.id == content['result_id']).first()
            if query:
                if {'result': query.result, 'bug_url': query.bug_url, 'bug_des': query.bug_des} == content:
                    return query.id
                query.case_id = content.get('case_id')
                query.project_version = content.get('project_version')
                query.result = content.get('result')
                query.bug_url = content.get('bug_url')
                query.bug_des = content.get('bug_des')
                query.person = content.get('person')
                query.last_time = str(datetime.datetime.now())
                db.session.commit()
                return query.id
    id = CaseResult(case_id=content['case_id'],
                    project_id=content['project_id'],
                    case_version=content['case_version'],
                    project_version=content['project_version'],
                    result=content['result'],
                    bug_url=content['bug_url'],
                    bug_des=content['bug_des'],
                    person=content['person']).add()
    return id


def case_result_history(caseId, resultId):
    """根据caseID查询历史缺陷的情况"""
    list = []
    query = CaseResult.query.filter(
        and_(CaseResult.case_id == caseId, CaseResult.result == "FAIL", CaseResult.id != resultId))
    query = query.all()
    for d in query:
        c = d.__dict__
        del (c['_sa_instance_state'])
        list.append(c)
    return list


def case_result_delete(id):
    query = CaseResult.query.filter(and_(CaseResult.id == id)).first()
    if query:
        db.session.delete(query)
        db.session.commit()
        return True
    return False


def case_result_get_allDoVersion(project_id):
    list = []
    query = CaseResult.query.filter(CaseResult.project_id == project_id)
    query = query.group_by(CaseResult.project_version)
    query = query.all()
    for d in query:
        c = d.__dict__
        del (c['_sa_instance_state'])
        list.append(c)
    return list


def case_result_search(project_id, project_version, result, key_words, page, limit):
    query = db.session().query(BaseCase, CaseResult)
    query = query.join(BaseCase, and_(BaseCase.id == CaseResult.case_id, BaseCase.case_plan == CaseResult.case_version))
    if project_id != "":
        query = query.filter(CaseResult.project_id == project_id)
    if project_version != "":
        query = query.filter(CaseResult.project_version.in_(project_version.split(',')))
    if result != "":
        query = query.filter(CaseResult.result.in_(result.split(',')))
    if key_words != "":
        key_words = "%%%s%%" % key_words
        query = query.filter(or_(BaseCase.case_require_no.like(key_words),
                                 BaseCase.case_no.like(key_words),
                                 BaseCase.case_main_mod.like(key_words),
                                 BaseCase.case_second_mod.like(key_words),
                                 BaseCase.case_pri.like(key_words),
                                 BaseCase.case_pre.like(key_words),
                                 BaseCase.case_title.like(key_words),
                                 BaseCase.case_step.like(key_words),
                                 BaseCase.case_expect.like(key_words),
                                 CaseResult.bug_des.like(key_words),
                                 CaseResult.bug_url.like(key_words),
                                 BaseCase.case_note.like(key_words)))
    query = query.filter(BaseCase.is_show == 0)
    count = query.count()
    data = query.paginate(int(page), int(limit), False)
    list = []
    for d in data.items:
        c_base = d.BaseCase.__dict__
        b_res = d.CaseResult.__dict__
        # c = d.__dict__
        up_person = c_base['up_person']
        up_person = UserManage.userBussiness.getNameById(up_person)
        c_base['up_person_name'] = up_person
        person = UserManage.userBussiness.getNameById(b_res['person'])
        b_res['person'] = person
        #   根据id和project_version去结果库进行查询
        del (b_res['_sa_instance_state'])
        del (c_base['_sa_instance_state'])
        list.append(dict(b_res, **c_base))

    return list, count


def case_result_sys_byModule(project_id, project_version):
    """根据项目、测试任务来统计每个模块的进度情况"""
    #   根据project_version获取测试案例的版本
    query = CaseResult.query.filter(
        and_(CaseResult.project_id == project_id, CaseResult.project_version.in_(project_version.split(','))))
    query = query.group_by(CaseResult.case_version)
    query = query.all()
    case_version_list = []
    for q in query: case_version_list.append(q.case_version)

    # 根据项目ID、用例版本获取总计用例的情况、以及所有模块的情况
    queryBase = BaseCase.query.filter(
        and_(BaseCase.project_id == project_id, BaseCase.case_plan.in_(case_version_list)))
    queryBase = queryBase.filter(BaseCase.is_show == 0)
    # 总计所有用例的数量
    queryBaseCount = queryBase.count()

    queryBase = queryBase.group_by(BaseCase.case_main_mod)
    queryBase = queryBase.all()
    list = []
    # 根据模块来进行统计查询
    for b in queryBase:
        queryByModule = db.session().query(BaseCase, CaseResult)
        queryByModule = queryByModule.join(BaseCase, BaseCase.id == CaseResult.case_id)
        # 统计结果表中的数据
        if project_version != "":
            queryByModule = queryByModule.filter(CaseResult.project_version.in_(project_version.split(',')))
        queryByModule = queryByModule.filter(CaseResult.case_version.in_(case_version_list))
        queryByModule = queryByModule.filter(BaseCase.case_main_mod == b.case_main_mod)
        # PASS的数据
        passCount = queryByModule.filter(CaseResult.result == "PASS").count()
        failCount = queryByModule.filter(CaseResult.result == "FAIL").count()
        blockCount = queryByModule.filter(CaseResult.result == "BLOCK").count()
        ntCount = queryByModule.filter(CaseResult.result == "NT").count()
        # 该模块一共拥有的用例的数量
        queryBaseTotalByMod = BaseCase.query.filter(
            and_(BaseCase.project_id == project_id, BaseCase.case_plan.in_(case_version_list)))
        mainModCount = queryBaseTotalByMod.filter(BaseCase.case_main_mod == b.case_main_mod).count()

        doCaseCount = passCount + failCount + blockCount + ntCount

        main_process = round(doCaseCount/mainModCount,2) *100
        FailRate = round(failCount/mainModCount,2)*100
        PassRate = round(passCount/mainModCount,2)*100

        list.append({'PassRate':PassRate,'main_moudle': b.case_main_mod, 'PASS': passCount, 'FAIL': failCount,
                     'BLOCK': blockCount, 'NT': ntCount, "total": mainModCount,'main_process':main_process,'FailRate':FailRate})
    return list,queryBaseCount


def caseResult_byTask(project_id,project_version,case_version,moudle_list):
    """有多少用例已经被执行，供查询子任务状态时调用"""
    countResultMod = 0
    countCaseMod = 0
    queryBase = BaseCase.query.filter(and_(BaseCase.project_id == project_id, BaseCase.case_plan == case_version,
                                           BaseCase.case_main_mod.in_(moudle_list.split(','))))

    #我的任务拥有模块的用例数
    countCaseMod = queryBase.count()
    caseIdList = []
    for d in queryBase.all():
        caseIdList.append(d.id)
    #已经有的结果数
    if(len(caseIdList))>0:
        queryResult = CaseResult.query.filter(and_(CaseResult.case_id.in_(caseIdList),CaseResult.project_version==project_version))
        countResultMod = queryResult.count()
        return round(countResultMod/countCaseMod,2) *100
    return 0
